<?php

namespace App\common\Plugins\ThirdPartyLogin\Lib;

/* *
 * 类名：WeChatApi
 */

use Illuminate\Support\Facades\Cache;

class WeChatApi {
    //===========【基本信息设置】===========
    //微信公众号身份的唯一标识 （小程序）
    protected $APPID = '';  //填写您的appid，微信公众平台里的
    protected $APPSECRET = '';
    //受理商ID,身份标识
    protected $MCHID = '';  //商户id
    //商户支付密钥Key
    protected $KEY = '';
    //回调通知接口
    protected $URL = '';

    //微信的构造函数
    function __construct() {
    }

    public function setConfig($name, $value = '') {
        $this->$name = $value;
    }

    //回调获取数据
    function getData() {
        if ($GLOBALS['HTTP_RAW_POST_DATA']) {
            $data = $GLOBALS['HTTP_RAW_POST_DATA'];
        } else if ($_POST['HTTP_RAW_POST_DATA']) {
            $data = $_POST['HTTP_RAW_POST_DATA'];
        } else if ($_GET['HTTP_RAW_POST_DATA']) {
            $data = $_GET['HTTP_RAW_POST_DATA'];
        } else {
            $data = file_get_contents('php://input');
        }
        return $data;
    }

    //参数1：访问的URL，参数2：post数据(不填则为GET)，参数3：提交的$cookies,参数4：是否返回$cookies
    function curl_request($url, $post = '', $cookie = '', $returnCookie = 0, $json = false, $header = array()) {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 0);
        curl_setopt($curl, CURLOPT_AUTOREFERER, 0);
        //curl_setopt($curl, CURLOPT_REFERER, "http://XXX");
        if ($post && !$json) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
        }
        if ($json) {
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
            curl_setopt($curl, CURLOPT_HTTPHEADER, array_merge(array(
                    'Content-Type: application/json; charset=utf-8',
                    //伪造IP
                    //'CLIENT-IP:85.25.105.77','X-FORWARDED-FOR:85.25.105.77',//此处可以改为任意假IP
                    'Content-Length: ' . strlen($post)
                ), $header)
            );
        }
        if ($cookie) {
            curl_setopt($curl, CURLOPT_COOKIE, $cookie);
        }
        curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
        curl_setopt($curl, CURLOPT_TIMEOUT, 60);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        //不输出头信息
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        $data = curl_exec($curl);
        if (curl_errno($curl)) {
            //return false;
            throw new \Exception("Error:" . curl_error($curl));
        }
        curl_close($curl);
        if ($returnCookie) {
            list($header, $body) = explode("\r\n\r\n", $data, 2);
            preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
            $info['cookie'] = substr($matches[1][0], 1);
            $info['content'] = $body;
            return $info;
        } else {
            return $data;
        }
    }

    //获取微信公众号code
    public function publicGetCode($data) {
        $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid=' . $this->APPID . '&redirect_uri=' . urlencode($data['callback']) . '&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect';
        return $url;
    }

    //获取微信PC code
    public function pcGetCode($data) {
        $url = "https://open.weixin.qq.com/connect/qrconnect?appid=$this->APPID&scope=snsapi_login&response_type=code&redirect_uri=urlencode($data[callback])#wechat_redirect";
        return $url;
    }

    //微信公众号获取token和openid
    public function publicCodeGetWeChatInfo($data) {
        $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' . $this->APPID . '&secret=' . $this->APPSECRET . '&code=' . $data['code'] . '&grant_type=authorization_code';
        $res = $this->curl_request($url);
        //解析
        $wx = json_decode($res, true);
        return $wx;
    }

    //微信公众号获取token和openid
    public function publicTokenGetWeChatUserInfo($data) {
        $user_info = $this->curl_request('https://api.weixin.qq.com/sns/userinfo?access_token=' . $data['access_token'] . '&openid=' . $data['openid'] . '&lang=zh_CN');
        $user_info = json_decode($user_info, true);
        //解析
        return $user_info;
    }

    //微信小程序获取token和openid
    public function smallCodeGetWeChatInfo($data) {
        $url = "https://api.weixin.qq.com/sns/jscode2session?appid=$this->APPID&secret=$this->APPSECRET&js_code=$data[code]&grant_type=authorization_code";
        $res = $this->curl_request($url);
        //解析
        $wx = json_decode($res, true);
        return $wx;
    }

    //微信公众号分享
    public function publicShare($data) {
        //获取参数
        $url = $data['url'];
        //公众号的appid、secret
        $appid = $this->APPID;
        $secret = $this->APPSECRET;
        //缓存内是否存在accessToken。
        /*        $accessToken = Cache::remember('WXAccessToken', 120, function () use ($appid, $secret) {
                    //获取access_token的请求地址
                    $accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
                    //请求地址获取access_token
                    $accessTokenJson = file_get_contents($accessTokenUrl);
                    $accessTokenObj = json_decode($accessTokenJson);
                    $accessToken = $accessTokenObj->access_token;
                    return $accessToken;
                });*/
        //$accessToken = Cache::get('accessToken');
        //$jsapiTicket = Cache::get('jsapiTicket');
        //if (!$accessToken || !$jsapiTicket) {
        //获取access_token的请求地址
        $accessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$secret";
        //请求地址获取access_token
        $accessTokenJson = file_get_contents($accessTokenUrl);
        $accessTokenObj = json_decode($accessTokenJson);
        $accessToken = $accessTokenObj->access_token;
        Cache::put('accessToken', $accessToken, 100);

        //获取jsapi_ticket的请求地址
        $ticketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=$accessToken&type=jsapi";
        $jsapiTicketJson = file_get_contents($ticketUrl);
        $jsapiTicketObj = json_decode($jsapiTicketJson);
        $jsapiTicket = $jsapiTicketObj->ticket;
        Cache::put('jsapiTicket', $jsapiTicket, 100);
        //}
        //随机生成16位字符
        $noncestr = str_random(16);
        //时间戳
        $time = time() . '';
        //拼接string1
        $jsapiTicketNew = "jsapi_ticket=$jsapiTicket&noncestr=$noncestr&timestamp=$time&url=$url";

        //对string1作sha1加密
        $signature = sha1($jsapiTicketNew);
        //存入数据
        $data = [
            'appId' => $appid,
            'timestamp' => $time,
            'nonceStr' => $noncestr,
            'signature' => $signature,
            'jsapiTicket' => $jsapiTicket,
            'url' => $url,
            'jsApiList' => [
                'api' => '#'
            ]
        ];
        return $data;
    }

    function curl_json_request($url, $data) {
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => "POST",
            CURLOPT_POSTFIELDS => $data,
            CURLOPT_HTTPHEADER => array(
                "Content-Type: application/json"
            ),
        ));
        $response = curl_exec($curl);
        curl_close($curl);
        return $response;
    }

    public function generatingQROfSmallProgram($data) {

        //获取access_token
        $access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->APPID&secret=$this->APPSECRET";
        $access_token = json_decode(file_get_contents(dirname(__DIR__) . '/access_token.json'), true);
        if (!isset($access_token['access_token']) || (isset($access_token['expires_in']) && time() > $access_token['expires_in'])) {
            $json = $this->curl_request($access_token_url);
            $json = json_decode($json, true);
            $add['access_token'] = $json['access_token'];
            $add['expires_in'] = time() + $json['expires_in'] - 100;
            $ACCESS_TOKEN = $json["access_token"];
            file_put_contents(dirname(__DIR__) . '/access_token.json', json_encode($add));
        } else {
            $ACCESS_TOKEN = $access_token["access_token"];
        }

        //构建请求二维码参数
        //适用于需要的码数量较少的业务场景。通过该接口生成的小程序码，永久有效，有数量限制
        // $qcode ="https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=$ACCESS_TOKEN";
        // $param = json_encode(array("path"=>"PackageTab1/orderDetails/orderDetails?order_no=200509101229710907","width"=> 150));


        //适用于需要的码数量极多的业务场景。通过该接口生成的小程序码，永久有效，数量暂无限制
        $qcode = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=$ACCESS_TOKEN";
        //$param = json_encode(array("page" => "PackageTab1/orderDetails/orderDetails", "scene" => "order_no=200509101229710907", "width" => 150));
        $param = ["page" => $data["page"], "scene" => $data["scene"], "width" => $data["width"] ?: 200];
        //POST参数
        $result = $this->curl_json_request($qcode, json_encode($param));
        $res = json_decode($result, true);
        $path = '/smallCode';
        if (!is_dir(public_path($path))) mkdir(public_path($path), 0777);
        if ($data["save_path"]) $path .= '/' . $data["save_path"];
        if ($data["save_path"] && !is_dir(public_path($path))) mkdir(public_path($path), 0777);
        $path .= '/' . date('Y');
        if (!is_dir(public_path($path))) mkdir(public_path($path), 0777);
        $path .= '/' . date('m');
        if (!is_dir(public_path($path))) mkdir(public_path($path), 0777);
        $path .= '/' . date('d');
        if (!is_dir(public_path($path))) mkdir(public_path($path), 0777);

        if ($res['errcode'] > 0) {
            return ['status' => 0, 'msg' => $res['errmsg']];
        }
        //生成二维码
        $path .= "/{$data["id"]}.png";
        file_put_contents(".{$path}", $result);
        $param['url'] = $path;
        return ['status' => 200, 'msg' => '获取成功', 'data' => $param];
    }
}

